package com.zhx.common.common.event.Listener;


import com.zhx.common.chat.dao.MessageDao;
import com.zhx.common.chat.dao.MessageMarkDao;
import com.zhx.common.chat.domain.dto.ChatMessageMarkDTO;
import com.zhx.common.chat.domain.entity.Message;
import com.zhx.common.chat.domain.enums.MessageMarkTypeEnum;
import com.zhx.common.chat.domain.enums.MessageTypeEnum;
import com.zhx.common.common.event.MessageMarkEvent;
import com.zhx.common.user.domain.enums.IdempotentEnum;
import com.zhx.common.user.domain.enums.ItemEnum;
import com.zhx.common.user.service.IUserBackpackService;
import com.zhx.common.user.service.adapter.WSAdapter;
import com.zhx.common.user.service.impl.PushService;
import com.zhx.common.websocket.domain.vo.resp.WSBaseResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

import javax.annotation.Resource;
import java.util.Objects;

@Component
public class MessageMarkListener{

    @Resource
    private MessageDao messageDao;
    @Resource
    private MessageMarkDao messageMarkDao;
    @Autowired
    private IUserBackpackService userBackpackService;
    @Resource
    private PushService pushService;
    /**
     * 异步处理消息类型变更事件。
     * 当监听到特定的消息标记事件（MessageMarkEvent）时，根据消息的标记类型和数量，以及消息的原始状态，
     * 对消息进行处理，例如改变消息的状态或触发某些用户奖励。
     *
     * @param event 消息标记事件，包含需要处理的消息标记详细信息。
     *              事件中包含的消息标记DTO（MessageMarkDTO）提供了消息ID、标记类型等关键信息。
     */
    @Async
    @TransactionalEventListener(classes = MessageMarkEvent.class,fallbackExecution = true)
    public void changeMsgType(MessageMarkEvent event){
        // 从事件中获取消息标记DTO，并根据DTO获取相关消息
        ChatMessageMarkDTO messageMarkDTO = event.getMessageMarkDTO();
        Message message = messageDao.getById(messageMarkDTO.getMsgId());

        // 如果消息状态不是文本类型，则直接返回不进行处理
        if(!Objects.equals(message.getStatus(), MessageTypeEnum.TEXT.getType())){
            return;
        }

        // 获取当前标记类型(点赞或点踩)的消息标记数量，并根据标记类型判断是否达到触发条件
        Integer count = messageMarkDao.getMarkCount(messageMarkDTO.getMsgId(),messageMarkDTO.getMarkType());
        MessageMarkTypeEnum msgMarkTypeEnum = MessageMarkTypeEnum.of(messageMarkDTO.getMarkType());
        // 如果标记数量小于触发/升级条件，则直接返回不进行处理
        if(count < msgMarkTypeEnum.getRiseNum()){
            return;
        }

        // 如果标记类型为点赞，则触发用户背包物品获取流程
        if(MessageMarkTypeEnum.LIKE.getType().equals(messageMarkDTO.getMarkType())){
            userBackpackService.acquireItem(message.getFromUid(), ItemEnum.LIKE_BADGE.getId(), IdempotentEnum.MSG_ID,message.getId().toString());
        }
    }


    @Async
    @TransactionalEventListener(classes = MessageMarkEvent.class,fallbackExecution = true)
    public void sendToAll(MessageMarkEvent event){
        ChatMessageMarkDTO dto = event.getMessageMarkDTO();
        Integer markCount = messageMarkDao.getMarkCount(dto.getMsgId(), dto.getMarkType());
        pushService.sendPushMsg(WSAdapter.buildMsgMarkSend(dto,markCount));
    }

}
